<!-- z-paging聊天输入框 -->
<template>
	<view class="chat-input-bar-container" @touchmove.stop>
		<view class="reply" v-show="reply">
			<div class="reply-content">
				<span>{{currentMsg?.username ? currentMsg?.username : currentMsg?.fromname}}</span>
				<span>: </span>
				<span style="margin-left: 6px;" v-html="replyData"></span>
			</div>
			<div>
				<up-icon name="close-circle" top="2" size="20" @click="closeReply"></up-icon>
			</div>
		</view>
		<view class="chat-input-bar">
			<view class="chat-input-container">
				<textarea
					id="pasteArea"
					:style="{ height: textareaHeight + 'px', overflow: textareaHeight >= maxHeight ? 'auto' : 'hidden' }"
					:focus="focus"
					:maxlength="-1"
					class="chat-input"
					v-model="msg"
					:adjust-position="false"
					confirm-type="return"
					:show-confirm-bar="false"
					placeholder="请输入内容"
					@input="handleInput"
					@linechange="handleLineChange"
					@focus="onFocus"
				></textarea>
			</view>
			<!-- 表情图标（如果不需要切换表情面板则不用写） -->
			<view class="emoji-container">
				<image class="emoji-img" src="/static/chat/smile.png" @click="emojiChange('emoji')"></image>
			</view>
			<view v-if="msg == ''" class="emoji-container">
				<image class="emoji-img" src="/static/chat/add-circle.png" @click="emojiChange('more')"></image>
			</view>
			<view v-if="msg != ''" :class="{'chat-input-send': true, 'chat-input-send-disabled': !sendEnabled}" @click="throttleFetch">
				<text class="chat-input-send-text">发送</text>
			</view>
		</view>
		<!--  表情面板，这里使用height控制隐藏显示是为了有高度变化的动画效果（如果不需要切换表情面板则不用写） -->
		<view class="emoji-panel-container" :style="[{height: emojiType === 'keyboard' ? emojiShow == 'emoji' ? '400rpx' : '200rpx' : '0px'}]">
			<scroll-view v-show="emojiShow == 'emoji'" scroll-y style="height: 100%;flex: 1;">
				<view class="emoji-panel">
					<text class="emoji-panel-text" v-for="(item, index) in emojisArr" :key="index" @click="emojiClick(item)">
						{{item}}
					</text>
				</view>
			</scroll-view>

			<view class="more-box" v-show="emojiShow == 'more'">
				<view v-if="!isGroup" style="display: flex !important; justify-content: center; align-items: center;" class="more-item" @click="callPhone">
					<u-icon size="38" color="#333" name="phone-fill"></u-icon>
				</view>
				<view class="more-item" @tap="chooseImage">
					<tui-icon size="38" color="#333" name="pic-fill"></tui-icon>
				</view>
				<view class="more-item" @tap="chooseCamera">
					<tui-icon size="38" color="#333" name="camera-fill"></tui-icon>
				</view>
				<view class="more-item" @tap="chooseFile">
					<image style="width: 40px; height: 40px;" src="/static/chat/folder.png"></image>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	import { throttle } from "@/utils/index.js"
	// import pasteMixin from '@/pages/chat/message/config/paste.js';
	export default {
		name:"chat-input-bar",
		// mixins: [pasteMixin],
		props: {
			disabled: {
				type: Boolean,
				default: false
			},
			isGroup: {
				type: Boolean,
				default: false
			},
			dialogId: {
				type: String,
				default: ''
			},
			groupId: {
				type: String,
				default: ''
			},
		},
		data() {
			return {
				msg: '',
				// 表情数组（如果不需要切换表情面板则不用写）
				emojisArr: ['😊','😁','😀','😃','😣','😞','😩','😫','😲','😟','😦','😜','😳','😋','😥','😰','🤠','😎','😇','😉','😭','😈','😕','😏','😘','😤','😡','😅','😬','😺','😻','😽','😼','🙈','🙉','🙊','🔥','👍','👎','👌','✌️','🙏','💪','👻'],
				// 当前input focus（如果不需要切换表情面板则不用写）
				focus: false,
				// 当前表情/键盘点击后的切换类型，为空字符串代表展示表情logo但是不展示不展示表情面板（如果不需要切换表情面板则不用写）
				emojiType: '',
				emojiShow: '',
				textareaHeight: 24, // 初始高度，根据单行行高设定
				lineCount: 1, // 当前行数
				maxLine: 4, // 最大行数限制
				lineHeight: 24, // 预估的每行行高（需根据实际字体大小调整，单位px）
				maxHeight: 80, // 计算得到的最大高度
				oldContent: '',
				cursor: 0,
				atBlocks: [],
				reply: false,
				replyData: '',
				currentMsg: null,
				timer: null,
				chatInputCache: {},
			};
		},
		computed: {
			sendEnabled() {
				return !this.disabled && this.msg.length
			}
		},
		// watch: {
		// 	msg(value, old) {
		// 		const substringsToRemove = [':/image', ':/img/text'];
		// 		const isContain = substringsToRemove.find(item => value.includes(item));
		// 		if(isContain) {
		// 			this.handlePaste(isContain);
		// 		}
		// 	}
		// },
		created() {
			let cache = uni.getStorageSync('chatInputCache');
			this.chatInputCache = cache ? cache : {};
			if(cache[`group_${this.groupId}`] || cache[`chat_${this.dialogId}`]) {
				this.msg = cache[`group_${this.groupId}`] || cache[`chat_${this.dialogId}`];
			}	
		},
		methods: {
			copyCancel() {
				this.msg = '';
				if(this.isGroup) {
					this.chatInputCache[`group_${this.groupId}`] = '';
				}else {
					this.chatInputCache[`chat_${this.dialogId}`] = '';
				}
				uni.setStorageSync('chatInputCache', this.chatInputCache);
			},
			closeReply() {
				this.currentMsg = null;
				this.reply = false;
				this.replyData = '';
			},
			htmlToText(html) {
				if (!html) return '';
				return html
					.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '')
					.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '')
					.replace(/<[^>]+>/g, '')
					.replace(/&nbsp;/gi, ' ')
					.replace(/&lt;/gi, '<')
					.replace(/&gt;/gi, '>')
					.replace(/&amp;/gi, '&')
					.trim();
			},
			throttleFetch: throttle(function () {
				this.sendClick();
			}, 200),
			getQuoteContext(content) {
				let { type, content: txtContent, name } = content
				switch (type) {
					case 'text':
						this.replyData = txtContent;
						break;
					case 'file':
						this.replyData = `[文件] ${name}`;
						break;
					case 'dir':
						this.replyData = `[文件夹] ${name}`;
						break;
					case 'img/text':
						this.replyData = `[图片] ${this.htmlToText(txtContent)}`;
						break;
					case 'img':
						this.replyData = `[图片]`;
						break;
					default:
						this.replyData = '';
				}
			},
			setReplyContent(currentMsg) {
				this.currentMsg = currentMsg;
				this.reply = true;
				if(currentMsg.content) {
					let { content, username } = currentMsg;
					content.forEach(i => {
						if(i.content != '') {
							this.getQuoteContext(i);
						}
					});
				}
			},
			handleLineChange(event) {
				const {
					lineCount,
					height
				} = event.detail;
				this.lineCount = lineCount;

				// 如果当前行数小于最大行数限制，则更新高度
				if (lineCount <= this.maxLine) {
					this.textareaHeight = height; // 或者使用 lineCount * this.lineHeight
				} else {
					// 超过最大行数，高度设置为最大高度，允许内部滚动
					this.textareaHeight = this.maxHeight;
				}
			},
			// 更新了键盘高度（如果不需要切换表情面板则不用写）
			updateKeyboardHeightChange(res) {
				if (res.height > 0) {
					// 键盘展开，将emojiType设置为emoji
					this.emojiType = 'emoji';
				}
			},
			// 用户尝试隐藏键盘，此时如果表情面板在展示中，应当隐藏表情面板，如果是键盘在展示中不用处理，z-paging内部已经处理（如果不需要切换表情面板则不用写）
			hidedKeyboard() {
				if (this.emojiType === 'keyboard') {
					this.emojiType = '';
				}
			},
			onFocus() {
				this.emojiType = '';
			},
			// 点击了切换表情面板/键盘（如果不需要切换表情面板则不用写）
			emojiChange(isEmoji) {
				// this.$emit('emojiTypeChange', this.emojiType);
				if(this.emojiType === 'keyboard') {
					if(this.emojiShow == isEmoji) {
						this.emojiType = 'emoji'
					}
				}else {
					this.emojiType = 'keyboard'
				}
				this.emojiShow = isEmoji === 'emoji' ? 'emoji' : 'more'
				this.focus = false;
				uni.hideKeyboard();
			},
			// 点击了某个表情，将其插入输入内容中（如果不需要切换表情面板则不用写）
			emojiClick(text) {
				this.msg += text;
			},
			// 点击了发送按钮
			sendClick() {
				if (!this.sendEnabled) return;
				this.$emit('send', this.msg);
				this.setInputCache('');
			},
			callPhone() {
				this.$emit('callPhone');
			},
			chooseImage() {
				this.$emit('chooseImage');
			},
			chooseCamera() {
				this.$emit('chooseCamera');
			},
			chooseFile() {
				this.$emit('chooseFile');
			},
			setInputCache(content) {
				if (this.timer) {
					clearTimeout(this.timer);
				}
				this.timer = setTimeout(() => {
					if(this.isGroup) {
						this.chatInputCache[`group_${this.groupId}`] = content;
					}else {
						this.chatInputCache[`chat_${this.dialogId}`] = content;
					}
					uni.setStorageSync('chatInputCache', this.chatInputCache);
					this.timer = null; // 清空定时器
				}, 800);
			},
			handlePaste(val) {
				// 粘贴特定内容回滚
				uni.hideKeyboard();
				this.$nextTick(() => {
					this.$emit('copyShow', val);
					this.msg = '';
				});
				return;
			},
			async handleInput(event) {
				// 草稿
				this.setInputCache(event.detail.value);
				
				if(!this.isGroup) return;
				
				const value = event.detail.value
				const newCursor = event.detail.cursor
				
				// === 判断是否删除 ===
				if (value.length < this.oldContent.length) {
				  const cursor = newCursor
				
				  // 关键：退格后光标落在块范围内
				  const blockIndex = this.atBlocks.findIndex(
				    b => cursor > b.start && cursor < b.end
				  )
				
				  if (blockIndex !== -1) {
				    const block = this.atBlocks[blockIndex]
				    const length = block.end - block.start
				
				    const before = this.msg.slice(0, block.start)
				    const after = this.msg.slice(block.end)
				    this.msg = before + after
				
				    // 更新 oldContent 和 cursor
				    this.oldContent = this.msg
				    this.cursor = block.start
				
				    // 删除这个块
				    this.atBlocks.splice(blockIndex, 1);
				
				    // 更新后续块位置
				    this.atBlocks.forEach(b => {
				      if (b.start > block.start) {
				        b.start -= length
				        b.end -= length
				      }
				    })
				
				    return // 删除整块后不再继续处理
				  }
				}
				
				// === 正常输入 ===
				this.cursor = newCursor
				this.msg = value
				
				// 检查新增 @
				if (value.length > this.oldContent.length) {
				  const addedChar = value[newCursor - 1]
				  if (addedChar === '@') {
						this.$emit('handleMention')
				  }
				}
				
				// 更新 oldContent
				this.oldContent = value
			},
		}
	}
</script>

<style scoped>
	.chat-input-bar-container {
		position: relative;
		background-color: #f3f3f3;
		border-top: solid 1px #dfdfdf;
	}
	.reply {
		margin: 12px 14px 4px 20rpx;
		padding: 0 4px 4px 8px;
		font-size: 14px;
		line-height: 28px;
		background-color: rgba(0, 0, 0, .08);
		color: rgba(0, 0, 0, .7);
		border-radius: 4px;
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
		display: flex;
		align-items: center;
		transition: all .5s;
	}
	.reply-content {
		display: flex;
		align-items: center;
		width: 95%;
		overflow: hidden;
	}
	.chat-input-bar {
		display: flex;
		flex-direction: row;
		align-items: flex-end;
		padding: 10rpx 20rpx;
	}
	.chat-input-container {
		flex: 1;
		/* #ifndef APP-NVUE */
		display: flex;
		/* #endif */
		padding: 15rpx;
		background-color: white;
		border-radius: 10rpx;
		margin-bottom: 6rpx;
	}
	.chat-input {
		width: 100%;
		font-size: 32rpx;
	}
	.emoji-container {
		width: 54rpx;
		height: 54rpx;
		margin: 10rpx 0rpx 10rpx 20rpx;
	}
	.emoji-img {
		width: 54rpx;
		height: 54rpx;
	}
	.chat-input-send {
		background-color: #007AFF;
		margin: 10rpx 10rpx 10rpx 20rpx;
		border-radius: 10rpx;
		width: 110rpx;
		height: 60rpx;
		/* #ifndef APP-NVUE */
		display: flex;
		/* #endif */
		justify-content: center;
		align-items: center;
	}
	.chat-input-send-disabled {
		background-color: #bbbbbb;
	}
	.chat-input-send-text {
		color: white;
		font-size: 26rpx;
	}
	.emoji-panel-container {
		background-color: #eee;
		overflow: hidden;
		transition-property: height;
		transition-duration: 0.15s;
		/* #ifndef APP-NVUE */
		will-change: height;
		/* #endif */
	}
	.emoji-panel {
		font-size: 30rpx;
		/* #ifndef APP-NVUE */
		display: flex;
		/* #endif */
		flex-direction: row;
		flex-wrap: wrap;
		padding-right: 10rpx;
		padding-left: 15rpx;
		padding-bottom: 10rpx;
	}
	.emoji-panel-text {
		font-size: 50rpx;
		margin-left: 15rpx;
		margin-top: 20rpx;
	}
	.more-box {
		display: flex;
		justify-content: space-around;
		align-items: center;
		padding-top: 20px;
	}
	.more-item {
		display: flex;
		justify-content: center;
		align-items: center;
		width: 20%;
		padding: 10px 0;
		border-radius: 12px;
		background-color: rgba(0, 0, 0, .07);
	}
</style>